package com.dji.sample.wayline.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.aliyun.oss.common.utils.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dji.sample.common.constant.CommonConstant;
import com.dji.sample.common.error.ServiceException;
import com.dji.sample.common.model.*;
import com.dji.sample.common.util.DjKmlUtil;
import com.dji.sample.common.util.MinioUtil;
import com.dji.sample.common.util.kmlModel.TravelRecordRequest;
import com.dji.sample.component.oss.model.OssConfiguration;
import com.dji.sample.component.oss.service.impl.OssServiceContext;
import com.dji.sample.manage.dao.SysOrganizationMapper;
import com.dji.sample.manage.model.entity.SysOrganization;
import com.dji.sample.manage.service.DevicePlayLineInfoService;
import com.dji.sample.manage.service.DevicePositionService;
import com.dji.sample.manage.service.IDeviceService;
import com.dji.sample.wayline.dao.IWaylineFileMapper;
import com.dji.sample.wayline.model.dto.UploadKmlDto;
import com.dji.sample.wayline.model.dto.WaylineFileDTO;
import com.dji.sample.wayline.model.dto.WaylineInfoDto;
import com.dji.sample.wayline.model.entity.WaylineFileEntity;
import com.dji.sample.wayline.model.entity.WaylineFilePositionEntity;
import com.dji.sample.wayline.model.entity.WaylineInfoEntity;
import com.dji.sample.wayline.model.enums.LineTypeEnum;
import com.dji.sample.wayline.model.param.WaylineQueryParam;
import com.dji.sample.wayline.service.DevicePlayTaskDetailService;
import com.dji.sample.wayline.service.IWaylineFileService;
import com.dji.sample.wayline.service.WaylineFilePositionService;
import com.dji.sample.wayline.service.WaylineInfoService;
import io.minio.ObjectWriteResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.net.URL;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author sean
 * @version 0.3
 * @date 2021/12/22
 */
@Service
@Transactional
@Slf4j
public class WaylineFileServiceImpl implements IWaylineFileService {

    @Autowired
    private IWaylineFileMapper mapper;

    @Autowired
    private OssServiceContext ossService;

    @Autowired
    private OssConfiguration configuration;

    @Autowired
    DevicePlayLineInfoService devicePlayLineInfoService;

    @Autowired
    IDeviceService deviceService;

    @Autowired
    WaylineFilePositionService waylineFilePositionService;

    @Autowired
    DevicePlayTaskDetailService devicePlayTaskDetailService;

    @Autowired
    DevicePositionService devicePositionService;

    @Autowired
    WaylineInfoService waylineInfoService;

    @Autowired
    MinioUtil minioUtil;

    @Autowired
    DjKmlUtil kmlUtil;

    final Random random = new Random();

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    SysOrganizationMapper sysOrganizationMapper;

    @Override
    public PaginationData<WaylineFileDTO> getWaylinesByParam(String workspaceId, WaylineQueryParam param) {
        // Paging Query
        Page<WaylineFileEntity> page = mapper.selectPage(
                new Page<WaylineFileEntity>(param.getPage(), param.getPageSize()),
                new LambdaQueryWrapper<WaylineFileEntity>()
                        .likeRight(StringUtils.hasText(param.getOrgCode()), WaylineFileEntity::getOrgCode, param.getOrgCode())
                        .eq(StringUtils.hasText(workspaceId), WaylineFileEntity::getWorkspaceId, workspaceId)
                        .eq(StringUtils.hasText(param.getDeviceNo()), WaylineFileEntity::getDeviceNo, param.getDeviceNo())
                        .eq(param.isFavorited(), WaylineFileEntity::getFavorited, param.isFavorited())
                        .and(param.getTemplateType() != null, wrapper -> {
                            for (Integer type : param.getTemplateType()) {
                                wrapper.like(WaylineFileEntity::getTemplateTypes, type).or();
                            }
                        })
                        // There is a risk of SQL injection
                        .last(StringUtils.hasText(param.getOrderBy()), " order by " + param.getOrderBy()));

        // Wrap the results of a paging query into a custom paging object.
        List<WaylineFileDTO> records = page.getRecords()
                .stream()
                .map(this::entityConvertToDTO)
                .collect(Collectors.toList());
        return new PaginationData<>(records, new Pagination(page));
    }

    @Override
    public PaginationData<WaylineFileDTO> page(WaylineQueryParam param) {
        Page<WaylineFileEntity> page = mapper.page(param.getOrgCode(), param.getDeviceNo(), param.getStatus(), param.getName(), param.getType(), new Page<WaylineFileEntity>(param.getPage(), param.getPageSize()));
        List<WaylineFileDTO> records = page.getRecords()
                .stream()
                .map(this::entityConvertToDTO)
                .collect(Collectors.toList());
        return new PaginationData<>(records, new Pagination(page));
    }

    @Override
    public PaginationData<WaylineInfoEntity> getWaylinesByParam(WaylineQueryParam param) {
        Page<WaylineInfoEntity> page = waylineInfoService.page(new Page<WaylineInfoEntity>(param.getPage(), param.getPageSize()), new LambdaQueryWrapper<WaylineInfoEntity>()
                .likeRight(StringUtils.hasText(param.getOrgCode()), WaylineInfoEntity::getOrgCode, param.getOrgCode())
                .like(StringUtils.hasText(param.getDeviceNo()), WaylineInfoEntity::getDeviceNos, param.getDeviceNo())
                .eq(param.getStatus() != null, WaylineInfoEntity::getStatus, param.getStatus())
                .and(StringUtils.hasText(param.getSearchKey()), lineInfoEntityLambdaQueryWrapper -> lineInfoEntityLambdaQueryWrapper.like(StringUtils.hasText(param.getSearchKey()), WaylineInfoEntity::getName, param.getSearchKey())
                        .or()
                        .like(StringUtils.hasText(param.getSearchKey()), WaylineInfoEntity::getDeviceNos, param.getSearchKey()))
                // There is a risk of SQL injection
                .last(StringUtils.hasText(param.getOrderBy()), " order by " + param.getOrderBy()));
        for (WaylineInfoEntity record : page.getRecords()) {
            if (StringUtils.hasText(record.getDeviceNos())) {
                record.setDeviceNo(record.getDeviceNos().split(","));
            }
            if (record.getType() != null) {
                Optional<LineTypeEnum> optional = LineTypeEnum.getDescByCode(record.getType());
                optional.ifPresent(lineTypeEnum -> record.setTypeName(lineTypeEnum.getDesc()));
            }
        }
        return new PaginationData<>(page.getRecords(), new Pagination(page));
    }

    @Override
    public Optional<WaylineFileDTO> getWaylineByWaylineId(String workspaceId, String waylineId) {
        return Optional.ofNullable(
                this.entityConvertToDTO(
                        mapper.selectOne(
                                new LambdaQueryWrapper<WaylineFileEntity>()
                                        .eq(WaylineFileEntity::getWorkspaceId, workspaceId)
                                        .eq(WaylineFileEntity::getWaylineId, waylineId))));
    }

    @Override
    public URL getObjectUrl(String workspaceId, String waylineId) throws SQLException {
        Optional<WaylineFileDTO> waylineOpt = this.getWaylineByWaylineId(workspaceId, waylineId);
        if (waylineOpt.isEmpty()) {
            throw new SQLException(waylineId + " does not exist.");
        }
        return ossService.getObjectUrl(configuration.getBucket(), waylineOpt.get().getObjectKey());
    }

    @Override
    public Integer saveWaylineFile(String workspaceId, WaylineFileDTO metadata) {
        WaylineFileEntity file = this.dtoConvertToEntity(metadata);
        file.setWaylineId(UUID.randomUUID().toString());
        file.setWorkspaceId(workspaceId);

        byte[] object = ossService.getObject(configuration.getBucket(), metadata.getObjectKey());
        if (object.length == 0) {
            throw new RuntimeException("The file " + metadata.getObjectKey() +
                    " does not exist in the bucket[" + configuration.getBucket() + "].");
        }

        file.setSign(DigestUtils.md5DigestAsHex(object));
        int insertId = mapper.insert(file);
        return insertId > 0 ? file.getId() : insertId;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveBatch(UploadKmlDto uploadKmlDto, ObjectWriteResponse objectWriteResponse) {
        String key = UUID.randomUUID().toString();
        //添加一个主表？
        WaylineInfoEntity waylineInfoEntity = new WaylineInfoEntity();
        if (uploadKmlDto.getDeviceNo() != null && uploadKmlDto.getDeviceNo().length > 0) {
            String sns = Arrays.toString(uploadKmlDto.deviceNo).replace("[", "");
            sns = sns.replace("]", "").trim();
            if (StringUtils.hasText(sns)) {
                waylineInfoEntity.setDeviceNos(sns);
            }
        }
        BeanUtils.copyProperties(uploadKmlDto, waylineInfoEntity);
        if (waylineInfoEntity.getType() == null) {
            waylineInfoEntity.setType(LineTypeEnum.NORMAL.getCode());
        }
        waylineInfoEntity.setCreateTime(System.currentTimeMillis());
        waylineInfoEntity.setSign(objectWriteResponse.etag());
        waylineInfoEntity.setObjectKey(objectWriteResponse.object());
        waylineInfoEntity.setStatus(0);
        waylineInfoEntity.setUserName(uploadKmlDto.getUsername());
        waylineInfoEntity.setCreateTime(System.currentTimeMillis());
        waylineInfoEntity.setUpdateTime(System.currentTimeMillis());
        waylineInfoEntity.setUniKey(key);
        waylineInfoEntity.setPayloadInfo(JSONObject.toJSONString(uploadKmlDto.getPayloadInfo()));
        waylineInfoEntity.setDroneInfo(JSONObject.toJSONString(uploadKmlDto.getDroneInfo()));
        waylineInfoEntity.setPayloadParam(JSONObject.toJSONString(uploadKmlDto.getPayloadParam()));
        if (uploadKmlDto.getOriginCoordinate() != null) {
            waylineInfoEntity.setCoordinate(JSONObject.toJSONString(uploadKmlDto.getOriginCoordinate()));
        }
        if(waylineInfoEntity.getOrgId()!=null){
            SysOrganization sysOrganization = sysOrganizationMapper.selectById(waylineInfoEntity.getOrgId());
            if("90170006".equals(sysOrganization.getOrgLevel())){
                waylineInfoEntity.setStatus(1);
            }
        }

        waylineInfoService.save(waylineInfoEntity);

        List<TravelRecordRequest> list = uploadKmlDto.getTravelRecordRequests();
        List<WaylineFilePositionEntity> entityList = new ArrayList<>();
        WaylineFilePositionEntity waylineFilePositionEntity = null;
        for (TravelRecordRequest travelRecordRequest : list) {
            waylineFilePositionEntity = new WaylineFilePositionEntity(travelRecordRequest.lng, travelRecordRequest.lat, travelRecordRequest.height, key);
            waylineFilePositionEntity.setData(JSONObject.toJSONString(travelRecordRequest));
            entityList.add(waylineFilePositionEntity);
        }
        //保存点位
        waylineFilePositionService.saveBatch(entityList);
        //发送订阅消息添加站内信
        stringRedisTemplate.convertAndSend("dj.sendMsg", JSONObject.toJSONString(new MsgBody(waylineInfoEntity.getId().toString(), key, "flayTask", JSONObject.toJSONString(waylineInfoEntity))));

        if (uploadKmlDto.getDeviceNo() == null || uploadKmlDto.getDeviceNo().length == 0) {
            return;
        }
        Arrays.stream(uploadKmlDto.getDeviceNo()).forEach(s -> {
            WaylineFileEntity.WaylineFileEntityBuilder builder = WaylineFileEntity.builder();
            builder.workspaceId(CommonConstant.DEFAULT_WORK_SPACE_ID);
            builder.droneModelKey(s);
            builder.waylineId(UUID.randomUUID().toString());
            builder.payloadModelKeys("");
            builder.sign(objectWriteResponse.etag());
            builder.favorited(false);
            builder.templateTypes("0");
            builder.objectKey(objectWriteResponse.object());
            builder.orgCode(uploadKmlDto.getOrgCode());
            builder.orgId(uploadKmlDto.getOrgId());
            builder.deviceNo(s);
            builder.name(uploadKmlDto.getName());
            builder.username(uploadKmlDto.getUsername());
            builder.createTime(System.currentTimeMillis());
            builder.updateTime(System.currentTimeMillis());
            builder.startTime(uploadKmlDto.getEndTime());
            builder.endTime(uploadKmlDto.getEndTime());
            builder.uniKey(key);
            builder.type(uploadKmlDto.getType());
            mapper.insert(builder.build());
        });
    }

    @Override
    public Boolean markFavorite(String workspaceId, List<String> waylineIds, Boolean isFavorite) {
        if (waylineIds.isEmpty()) {
            return false;
        }
        if (isFavorite == null) {
            return true;
        }
        return mapper.update(null, new LambdaUpdateWrapper<WaylineFileEntity>()
                .set(WaylineFileEntity::getFavorited, isFavorite)
                .eq(WaylineFileEntity::getWorkspaceId, workspaceId)
                .in(WaylineFileEntity::getWaylineId, waylineIds)) > 0;
    }

    @Override
    public List<String> getDuplicateNames(String workspaceId, List<String> names) {
        return mapper.selectList(new LambdaQueryWrapper<WaylineFileEntity>()
                        .eq(WaylineFileEntity::getWorkspaceId, workspaceId)
                        .in(WaylineFileEntity::getName, names))
                .stream()
                .map(WaylineFileEntity::getName)
                .collect(Collectors.toList());
    }

    @Override
    public Boolean deleteByWaylineId(String workspaceId, String waylineId) {
        Optional<WaylineFileDTO> waylineOpt = this.getWaylineByWaylineId(workspaceId, waylineId);
        if (waylineOpt.isEmpty()) {
            return true;
        }
        WaylineFileDTO wayline = waylineOpt.get();
        boolean isDel = mapper.delete(new LambdaUpdateWrapper<WaylineFileEntity>()
                .eq(WaylineFileEntity::getWorkspaceId, workspaceId)
                .eq(WaylineFileEntity::getWaylineId, waylineId))
                > 0;
        if (!isDel) {
            return false;
        }
        return ossService.deleteObject(configuration.getBucket(), wayline.getObjectKey());
    }

    /**
     * Convert database entity objects into wayline data transfer object.
     *
     * @param entity
     * @return
     */
    private WaylineFileDTO entityConvertToDTO(WaylineFileEntity entity) {
        if (entity == null) {
            return null;
        }
        String typeName = "";
        if (entity.getType() != null) {
            Optional<LineTypeEnum> optional = LineTypeEnum.getDescByCode(entity.getType());
            if (optional.isPresent()) {
                typeName = optional.get().getDesc();
            }
        }
        SimpleDateFormat dateTimeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = dateTimeFormatter.format(new Date(entity.getUpdateTime()));
        return WaylineFileDTO.builder()
                .droneModelKey(entity.getDroneModelKey())
                .favorited(entity.getFavorited())
                .name(entity.getName())
                .payloadModelKeys(entity.getPayloadModelKeys() != null ?
                        Arrays.asList(entity.getPayloadModelKeys().split(",")) : null)
                .templateTypes(Arrays.stream(entity.getTemplateTypes().split(","))
                        .map(Integer::parseInt)
                        .collect(Collectors.toList()))
                .username(entity.getUsername())
                .objectKey(entity.getObjectKey())
                .sign(entity.getSign())
                .updateTime(entity.getUpdateTime())
                .waylineId(entity.getWaylineId())
                .deviceNo(entity.getDeviceNo())
                .uniKey(entity.getUniKey())
                .status(entity.getStatus())
                .type(entity.getType())
                .typeName(typeName)
                .createTime(time)
                .build();

    }

    /**
     * Convert the received wayline object into a database entity object.
     *
     * @param file
     * @return
     */
    private WaylineFileEntity dtoConvertToEntity(WaylineFileDTO file) {
        WaylineFileEntity.WaylineFileEntityBuilder builder = WaylineFileEntity.builder();

        if (file != null) {
            builder.droneModelKey(file.getDroneModelKey())
                    .name(file.getName())
                    .username(file.getUsername())
                    .objectKey(file.getObjectKey())
                    // Separate multiple payload data with ",".
                    .payloadModelKeys(String.join(",", file.getPayloadModelKeys()))
                    .templateTypes(file.getTemplateTypes().stream()
                            .map(String::valueOf)
                            .collect(Collectors.joining(",")))
                    .favorited(file.getFavorited())
                    .build();
        }

        return builder.build();
    }

    @Override
    public Boolean deleteByIdAndDeviceNo(Long id, String deviceNo) {
        QueryWrapper<WaylineFileEntity> queryWrapper = new QueryWrapper<WaylineFileEntity>().eq("id", id).eq("device_no", deviceNo);
        return mapper.delete(queryWrapper) > 0;
    }

    @Override
    public WaylineFileEntity selectById(Long id) {
        return mapper.selectById(id);
    }

    @Override
    public WaylineInfoEntity getDetail(Long id) {
        WaylineInfoEntity infoEntity = waylineInfoService.getBaseMapper().selectById(id);
        if (infoEntity == null) {
            return new WaylineInfoEntity();
        }
        if (StringUtils.hasText(infoEntity.getCoordinate())) {
            List<TravelRecordRequest> strings = JSONArray.parseArray(infoEntity.coordinate).toJavaList(TravelRecordRequest.class);
            infoEntity.setOriginCoordinate(strings);
            infoEntity.setCoordinate(null);
        }
        if (infoEntity.getType() != null) {
            Optional<LineTypeEnum> optional = LineTypeEnum.getDescByCode(infoEntity.getType());
            optional.ifPresent(lineTypeEnum -> infoEntity.setTypeName(lineTypeEnum.getDesc()));
        }
        List<WaylineFilePositionEntity> positionEntities = waylineFilePositionService.list(new LambdaQueryWrapper<WaylineFilePositionEntity>().in(WaylineFilePositionEntity::getUniKey, infoEntity.getUniKey()));
        infoEntity.setPositions(positionEntities);
        return infoEntity;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateWayInfo(UploadKmlDto uploadKmlDto) throws Exception {
        WaylineInfoEntity infoEntity = waylineInfoService.getById(uploadKmlDto.getId());
        if (infoEntity == null) {
            throw new ServiceException("数据不存在");
        }
        if (infoEntity.getStatus() != 0) {
            throw new ServiceException("该记录已审核或已驳回不可再修改");
        }
        ObjectWriteResponse objectWriteResponse = kmlUtil.setTravelsKml(uploadKmlDto.getTravelRecordRequests(), uploadKmlDto.getTakeOffSecurityHeight(), uploadKmlDto.getSpeed(), random.nextInt(65535), uploadKmlDto.getEllipsoidHeight());
        if (objectWriteResponse == null) {
            throw new ServiceException("新航线生成失败");
        }
        //不修改 删除重建
        minioUtil.remove(infoEntity.getObjectKey());
        waylineFilePositionService.remove(new LambdaUpdateWrapper<WaylineFilePositionEntity>().eq(WaylineFilePositionEntity::getUniKey, infoEntity.getUniKey()));
        mapper.delete(new LambdaUpdateWrapper<WaylineFileEntity>().eq(WaylineFileEntity::getUniKey, infoEntity.getUniKey()));
        if (StringUtils.hasText(infoEntity.getDeviceNos())) {
            uploadKmlDto.setDeviceNo(infoEntity.getDeviceNos().split(","));
        }
        saveBatch(uploadKmlDto, objectWriteResponse);
        waylineInfoService.removeById(uploadKmlDto.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteLineInfo(Long id) {
        WaylineInfoEntity infoEntity = waylineInfoService.getById(id);
        if (infoEntity == null) {
            throw new ServiceException("数据不存在");
        }
        if (infoEntity.getStatus() != 0) {
            throw new ServiceException("该记录已审核或已驳回不可删除");
        }
        minioUtil.remove(infoEntity.getObjectKey());
        waylineFilePositionService.remove(new LambdaUpdateWrapper<WaylineFilePositionEntity>().eq(WaylineFilePositionEntity::getUniKey, infoEntity.getUniKey()));
        mapper.delete(new LambdaUpdateWrapper<WaylineFileEntity>().eq(WaylineFileEntity::getUniKey, infoEntity.getUniKey()));
        waylineInfoService.removeById(id);
        stringRedisTemplate.convertAndSend("dj.sendMsg", JSONObject.toJSONString(new MsgBody(infoEntity.getId().toString(), infoEntity.getUniKey(), "flayTaskDelete", JSONObject.toJSONString(infoEntity))));
        return true;
    }

    @Override
    public List<WaylineFileEntity> findByIds(List<Long> ids) {
        return mapper.selectBatchIds(ids);
    }

    @Override
    public void addDevice(String[] nos, Long id) {
        WaylineInfoEntity infoEntity = waylineInfoService.getById(id);
        if (infoEntity == null) {
            throw new ServiceException("数据不存在");
        }
        if (infoEntity.getEndTime() != null && infoEntity.getEndTime().compareTo(new Date()) < 0) {
            throw new ServiceException("任务已结束");
        }
        String deviceNos = infoEntity.getDeviceNos();
        boolean flag = false;
        for (String s : nos) {
            if (!StringUtils.hasText(deviceNos)) {
                deviceNos = s;
            } else if (deviceNos.contains(s)) {
                continue;
            } else {
                deviceNos = deviceNos.concat(",").concat(s);
            }
            flag = true;
            //    mapper.delete(new LambdaUpdateWrapper<WaylineFileEntity>().eq(WaylineFileEntity::getUniKey,infoEntity.getUniKey()).eq(WaylineFileEntity::getDeviceNo,s));
            WaylineFileEntity.WaylineFileEntityBuilder builder = WaylineFileEntity.builder();
            builder.workspaceId(CommonConstant.DEFAULT_WORK_SPACE_ID);
            builder.droneModelKey(s);
            builder.waylineId(UUID.randomUUID().toString());
            builder.payloadModelKeys("");
            builder.sign(infoEntity.getSign());
            builder.favorited(false);
            builder.templateTypes("0");
            builder.objectKey(infoEntity.getObjectKey());
            builder.orgCode(infoEntity.getOrgCode());
            builder.orgId(infoEntity.getOrgId());
            builder.deviceNo(s);
            builder.name(infoEntity.getName());
            builder.username(infoEntity.getUserName());
            builder.createTime(System.currentTimeMillis());
            builder.updateTime(System.currentTimeMillis());
            builder.startTime(infoEntity.getEndTime());
            builder.endTime(infoEntity.getEndTime());
            builder.uniKey(infoEntity.getUniKey());
            builder.type(infoEntity.getType());
            mapper.insert(builder.build());
        }
        if (!flag) {
            return;
        }
        WaylineInfoEntity update = new WaylineInfoEntity();
        update.setId(id.intValue());
        update.setDeviceNos(deviceNos.trim());
        update.setUpdateTime(System.currentTimeMillis());
        waylineInfoService.updateById(update);
    }

    @Override
    public void reduceDevice(String[] nos, Long id) {
        WaylineInfoEntity infoEntity = waylineInfoService.getById(id);
        if (infoEntity == null) {
            throw new ServiceException("数据不存在");
        }
        if (infoEntity.getEndTime() != null && infoEntity.getEndTime().compareTo(new Date()) < 0) {
            throw new ServiceException("任务已结束");
        }
        String deviceNos = infoEntity.getDeviceNos();
        boolean flag = false;
        for (String s : nos) {
            if (!StringUtils.hasText(deviceNos)) {
                return;
            } else if (!deviceNos.contains(s)) {
                continue;
            } else {
                deviceNos = deviceNos.replace(s, "");
            }
            flag = true;
            mapper.delete(new LambdaUpdateWrapper<WaylineFileEntity>().eq(WaylineFileEntity::getUniKey, infoEntity.getUniKey()).eq(WaylineFileEntity::getDeviceNo, s));
        }
        if (!flag) {
            return;
        }
        WaylineInfoEntity update = new WaylineInfoEntity();
        update.setId(id.intValue());
        deviceNos = deviceNos.replace(",,", ",").trim();
        if (deviceNos.endsWith(",")) {
            deviceNos = deviceNos.substring(0, deviceNos.lastIndexOf(","));
        }
        update.setDeviceNos(deviceNos);
        if (deviceNos.length() == 1) {
            update.setDeviceNos("");
        } else {
            if (deviceNos.length() > 0 && deviceNos.charAt(0) == 44) {
                update.setDeviceNos(deviceNos.substring(1));
            }
        }
        update.setUpdateTime(System.currentTimeMillis());
        waylineInfoService.updateById(update);
    }

    @Override
    public WaylineInfoDto getDetailById(Long id) {
        WaylineInfoEntity infoEntity = waylineInfoService.getById(id);
        if (infoEntity == null) {
            return new WaylineInfoDto();
        }
        WaylineInfoDto waylineInfoDto = new WaylineInfoDto();
        BeanUtils.copyProperties(infoEntity, waylineInfoDto);
        if (infoEntity.getType() != null) {
            Optional<LineTypeEnum> optional = LineTypeEnum.getDescByCode(infoEntity.getType());
            optional.ifPresent(lineTypeEnum -> infoEntity.setTypeName(lineTypeEnum.getDesc()));
        }
        List<WaylineFilePositionEntity> positionEntities = waylineFilePositionService.list(new LambdaQueryWrapper<WaylineFilePositionEntity>().in(WaylineFilePositionEntity::getUniKey, infoEntity.getUniKey()));
        if (positionEntities.isEmpty()) {
            return waylineInfoDto;
        }
        for (WaylineFilePositionEntity positionEntity : positionEntities) {
            if (StringUtils.hasText(positionEntity.getData())) {
                TravelRecordRequest travelRecordRequest = JSONObject.parseObject(positionEntity.getData(), TravelRecordRequest.class);
                waylineInfoDto.addPositionDetail(travelRecordRequest);
            }
        }
        if (StringUtils.hasText(infoEntity.getDroneInfo())) {
            waylineInfoDto.setDroneInfo(JSONObject.parseObject(infoEntity.getDroneInfo(), UploadKmlDto.DroneInfo.class));
        }
        if (StringUtils.hasText(infoEntity.getPayloadInfo())) {
            waylineInfoDto.setPayloadInfo(JSONObject.parseObject(infoEntity.getPayloadInfo(), UploadKmlDto.PayloadInfo.class));
        }
        if (StringUtils.hasText(infoEntity.getPayloadParam())) {
            waylineInfoDto.setPayloadParam(JSONObject.parseObject(infoEntity.getPayloadParam(), UploadKmlDto.PayloadParam.class));
        }
        return waylineInfoDto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateV2wayInfo(UploadKmlDto uploadKmlDto) throws Exception {
        WaylineInfoEntity infoEntity = waylineInfoService.getById(uploadKmlDto.getId());
        if (infoEntity == null) {
            throw new ServiceException("数据不存在");
        }
        if (infoEntity.getStatus() != 0) {
            throw new ServiceException("该记录已审核或已驳回不可再修改");
        }
        ObjectWriteResponse objectWriteResponse = kmlUtil.setTravelsV2Kml(uploadKmlDto, UUID.randomUUID().toString());
        if (objectWriteResponse == null) {
            throw new ServiceException("新航线生成失败");
        }
        //不修改 删除重建
        minioUtil.remove(infoEntity.getObjectKey());
        waylineFilePositionService.remove(new LambdaUpdateWrapper<WaylineFilePositionEntity>().eq(WaylineFilePositionEntity::getUniKey, infoEntity.getUniKey()));
        mapper.delete(new LambdaUpdateWrapper<WaylineFileEntity>().eq(WaylineFileEntity::getUniKey, infoEntity.getUniKey()));
        if (StringUtils.hasText(infoEntity.getDeviceNos())) {
            uploadKmlDto.setDeviceNo(infoEntity.getDeviceNos().split(","));
        }
        saveBatch(uploadKmlDto, objectWriteResponse);
        waylineInfoService.removeById(uploadKmlDto.getId());
    }

}
